import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Base64;
import java.util.zip.Inflater;
import java.nio.charset.StandardCharsets;

/**
 * 测试：也许AES密钥是从输入参数派生的，而不是从ep解密得到
 */
public class TestEPDirectKey {
    
    // 输入参数
    private static final String ORGANIZATION = "qvdTr7A9k1DIU04ha4eP";
    private static final String APP_ID = "default";
    private static final long TIMESTAMP = 1761287286183L;
    
    private static final String DATA_BASE64 = "wHBy2LDIay6WCgEybO8bw/5OxmVd4N++OJpwr/Tgjw+TA8iZ4HAy4bN8UWtwmeGz+dqU/zX6myCireq+q465rqUqpXLhma2aEPqTaNvUTv/Y71kVpkMBkgrjMnVkIi/iBV5eKsrTPfLWO8bt0mSbLM8ghswC2m2YRInkqWXHrc8Nw0JsNjwCllOUdtwe3NuIx8oQuQ2fqj1G3g3xMp6B4sWBNAo+SjTNuKnS4chvbaD3RYnGvSLyNYu+sqbKeRNofCwVn0lVrjCAGtC9d5nqhFiGw0vWksPfmCRn7vRsl7LnqcXb+Fal/hhREBsaRJdMrst3vOEeQI6pt3RGKZ3VOsliNziKbLiNnXp2zY2fin32okAFwIOczPgeQA1yAM4FCnuT9FYAMn5ecAOY7WFhJPcOqVThy0giCJrBzpIzEHXTin+BWBO1PR8wMzBqpf6us9mhBZGzu40mzVN34xXK646aMr8f2DcD9yGO20v5icEz3OUcAeayMq+YKmBoypmvQUnaGa8pjr7RfvvajY+7pu6QHqRAQ3NLY1KjIoT3PKjabb7owQ1Txw5+Ajfjen7VEeF/Dq03nPMtNOpqD3tCdWDHWir+akJcEPtPzK4Bo2K3FrLBZt2igZD6/04jtwoAojHibKqUM1Rj5h2iijH65eAU1XKTpqDPNtcP5lwa1bFNV+GvuzHM+N4gcoxiELhQeG7xiUcsZrJvadkDO2z+If9vLkXTSdMKrqozUjLRapyXpULcVL8negHnj+2vKZVdoGiDhXlm23XDFjLY91ZqX2eGfGNmpJxftl83N6q4dyXpzD2gR/chHfm0CukVlL8P8aPAfEDcAsyQETc5oVLzetGVSkGBbQl+axZu8U2Ap9CXaTi1b2VcI3he19nvgG8XEFnwP6Tbicm5PDDsiRjo2MRqfuPLWkcSHTmBlS6w8yrzAvth9x/bBLg8XLs8M/B/dKSfOa9sbptfTMmEuuhWbnqCyqnFSUt8lsFlcUbJdK02TcMbd789pANnrKTTfFeOUehu5XReHng4DfV7f6boQmJPnZfwuR8qFwp7vwme235RTloktlkQu/2QFl2LmCv+/8Za43dEdFba9Ae6I1p+50zunyIjGTE6/9RT+g/zgagzgV/qDDSM5VF6E2Ic62W/KkpfSPMHAk5Jwg0LlsSMnFXYCynZoDZ5M8s62V15VaEII3s/6wPCu4lba/BxPanRtw60EVsvrJ7B0mnG+hcW8AGVeG1ZBIhgPH887/bY+05b0MnSkhjlrys8GKSaukVbtnrLJmjePt+LdLe6tH2NTwxjbHhJR028ZWaQKvdC5BD2hRflDMBPKL68D6YJ2bitqnKKdEqYHdCMXtOXh68XUqwfkoF3phQtYHyrqF4Wsgukf3/gAlt/yF0dXFTIUzoDTc34MEAaLFENVFDt4PUnYw2SRT8i/bhi3tcavu6Hnjs=";
    
    public static void main(String[] args) {
        try {
            System.out.println("=" + "=".repeat(99));
            System.out.println("测试：从输入参数派生AES密钥");
            System.out.println("=" + "=".repeat(99));
            
            byte[] dataWithIV = Base64.getDecoder().decode(DATA_BASE64);
            byte[] dataIV = Arrays.copyOfRange(dataWithIV, 0, 16);
            byte[] dataEncrypted = Arrays.copyOfRange(dataWithIV, 16, dataWithIV.length);
            
            System.out.println("\ndata IV: " + bytesToHex(dataIV));
            System.out.println("data 密文长度: " + dataEncrypted.length);
            
            // 尝试不同的密钥派生方式
            String[] inputs = {
                ORGANIZATION,
                APP_ID,
                String.valueOf(TIMESTAMP),
                ORGANIZATION + APP_ID,
                ORGANIZATION + APP_ID + TIMESTAMP,
                APP_ID + ORGANIZATION + TIMESTAMP,
                ORGANIZATION + TIMESTAMP,
                TIMESTAMP + ORGANIZATION + APP_ID
            };
            
            String[] algorithms = {"MD5", "SHA-1", "SHA-256"};
            
            for (String input : inputs) {
                for (String algo : algorithms) {
                    System.out.println("\n" + "-".repeat(100));
                    System.out.println("尝试: " + algo + "(\"" + (input.length() > 50 ? input.substring(0, 50) + "..." : input) + "\")");
                    
                    try {
                        MessageDigest md = MessageDigest.getInstance(algo);
                        byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
                        
                        // 如果hash长度不够32字节，继续hash
                        byte[] aesKey;
                        if (hash.length >= 32) {
                            aesKey = Arrays.copyOfRange(hash, 0, 32);
                        } else {
                            // MD5是16字节，hash两次拼接
                            byte[] hash2 = md.digest((input + input).getBytes(StandardCharsets.UTF_8));
                            aesKey = new byte[32];
                            System.arraycopy(hash, 0, aesKey, 0, Math.min(16, hash.length));
                            System.arraycopy(hash2, 0, aesKey, 16, Math.min(16, hash2.length));
                        }
                        
                        System.out.println("派生的密钥: " + bytesToHex(aesKey));
                        
                        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(aesKey, "AES"), new IvParameterSpec(dataIV));
                        byte[] decrypted = cipher.doFinal(dataEncrypted);
                        
                        System.out.println("✅ 解密成功！");
                        
                        // 尝试zlib解压
                        try {
                            Inflater inflater = new Inflater(true);
                            inflater.setInput(decrypted);
                            byte[] decompressed = new byte[1024 * 100];
                            int len = inflater.inflate(decompressed);
                            inflater.end();
                            
                            String json = new String(decompressed, 0, len, "UTF-8");
                            
                            System.out.println("\n🎉🎉🎉 成功！🎉🎉🎉");
                            System.out.println("密钥派生方式: " + algo + "(\"" + input + "\")");
                            System.out.println("\n解密后的JSON:");
                            System.out.println("=".repeat(100));
                            System.out.println(json);
                            System.out.println("=".repeat(100));
                            
                            System.exit(0);
                            
                        } catch (Exception e) {
                            System.out.println("  zlib解压失败: " + e.getMessage());
                        }
                        
                    } catch (Exception e) {
                        System.out.println("❌ 失败: " + e.getMessage());
                    }
                }
            }
            
            System.out.println("\n❌ 所有尝试都失败");
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}

